﻿#include "fridgedevice.h"

#include <QDebug>


FridgeDevice * FridgeDevice::m_fridgeDevice = NULL;
FridgeDevice::FridgeDevice(QObject *parent) : QObject(parent)
  , m_serial(NULL)
  , m_address(0x01)
  , m_minsTemp(-22)
  , m_maxsTemp(8)
  , m_cabinetTemp(0)
  , m_vaporTemp(0)
  , m_condenTemp(0)
  , m_sendDelayCmdTimer(NULL)
  , m_sendDelayCmdStatus(0)
  , m_openCmdTimer(NULL)
  , m_closeCmdTimer(NULL)
  , m_setTempCmdTimer(NULL)
  , m_isFridgeRuns(false)
  , m_deviceStatus(0)
{

    m_serial = new QSerialPort();
    connect(m_serial,SIGNAL( readyRead() ),this,SLOT( onDataReceived() ));
    m_sendDelayCmdTimer = new QTimer(this);
    connect(m_sendDelayCmdTimer,SIGNAL( timeout() ) ,this ,SLOT( onSendDelayCmdTimer() ) );

    m_openCmdTimer = new QTimer(this);
    connect(m_openCmdTimer,SIGNAL( timeout() ) ,this ,SLOT( onOpenDelayCmdTimer() ) );

    m_closeCmdTimer = new QTimer(this);
    connect(m_closeCmdTimer,SIGNAL( timeout() ) ,this ,SLOT( onCloseDelayCmdTimer() ) );

    m_setTempCmdTimer = new QTimer(this);
    connect(m_setTempCmdTimer,SIGNAL( timeout() ) ,this ,SLOT( onSetDelayCmdTimer() ) );

    for(int i =0;i <= 8 ; i++){
        m_callPoliceMap.insert(i,0);
    }
   // initComSeriel();

   // onSendDelayCmdTimer();
}

FridgeDevice::~FridgeDevice()
{

}

FridgeDevice *FridgeDevice::gestance()
{
    if(m_fridgeDevice == NULL){
        m_fridgeDevice = new FridgeDevice();
    }
    return m_fridgeDevice;

}

void FridgeDevice::initComSeriel()
{
    m_currentData.clear();
    QString names = "COM2";
#ifdef DEBUG_INFOR
    qDebug()<<"names=="<<names;
#endif
    if(names.length() > 0){
#ifdef DEBUG_INFOR
        qDebug()<<__func__<<__LINE__;
#endif
        QSerialPortInfo info(names);
        m_serial->setPortName(names);
        qDebug()<<__func__<<__LINE__<<"PortName=="<<names;
        m_serial->setBaudRate(QSerialPort::Baud9600);
        m_serial->setParity(QSerialPort::NoParity);
        m_serial->setDataBits(QSerialPort::Data8);
        m_serial->setStopBits(QSerialPort::OneStop);
        m_serial->setFlowControl(QSerialPort::NoFlowControl);

        if(m_serial->open(QIODevice::ReadWrite)) // 以读写方式打开串口
        {
            m_isFridgeRuns = true;
#ifdef DEBUG_INFOR
            qDebug()<<__func__<<__LINE__;
#endif
        }
#ifdef DEBUG_INFOR
        qDebug()<<__func__<<__LINE__;
#endif
    }

}

unsigned short FridgeDevice::count_CRC(unsigned char *addr, int num)
{
    unsigned short CRC = 0xFFFF;
    int i;
    while (num--)
    {
        CRC ^= *addr++;
        for (i = 0; i < 8; i++)
        {
            if (CRC & 1)
            {
                CRC >>= 1;
                CRC ^= 0xA001;
            }
            else
            {
                CRC >>= 1;
            }
        }
    }
    return CRC;
}

void FridgeDevice::openDevice()
{
    uint8_t address_pos = m_address;
    uint8_t ch[100];
    uint8_t tempa;
    uint32_t lens = 0;
    uint16_t check_crc=0;
    uint16_t cmds=0x0008;
    uint16_t runs=0xFF00;
    m_cmds =0x05;
    int nums =1;
    ch[0]= address_pos ;
    ch[1]=m_cmds;
    ch[2]=(uint8_t)(cmds >> 8);
    ch[3]=(uint8_t)(cmds);
    ch[4]=(uint8_t)(runs >> 8);
    ch[5]=(uint8_t)(runs);


    lens = 6;

    check_crc=count_CRC(ch,lens);

    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
    if(m_serial != NULL){
        m_serial->write(by);
        m_serial->flush();
    }
}

void FridgeDevice::closeDevice()
{
    uint8_t address_pos = m_address;
    uint8_t ch[100];
    uint8_t tempa;
    uint32_t lens = 0;
    uint16_t check_crc=0;
    uint16_t cmds=0x0008;
    uint16_t runs=0x0000;
    m_cmds =0x05;
    int nums =1;
    ch[0]= address_pos ;
    ch[1]=m_cmds;
    ch[2]=(uint8_t)(cmds >> 8);
    ch[3]=(uint8_t)(cmds);
    ch[4]=(uint8_t)(runs >> 8);
    ch[5]=(uint8_t)(runs);


    lens = 6;

    check_crc=count_CRC(ch,lens);

    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
    if(m_serial != NULL){
        m_serial->write(by);
        m_serial->flush();
    }
}

void FridgeDevice::setTemperature(short mins, short maxs)
{
    uint8_t address_pos = m_address;
    uint8_t ch[100];
    uint8_t tempa;
    uint32_t lens = 0;
    uint16_t check_crc=0;

    uint16_t starts=0x0006;
    uint16_t numa = 2;
    uint16_t numb = numa* 2;
    uint16_t numc =(uint16_t)mins;
    uint16_t numd =(uint16_t)maxs;
    m_cmds =0x10;
    int nums =1;
    ch[0]= address_pos ;
    ch[1]=m_cmds;
    ch[2]=(uint8_t)(starts >> 8);
    ch[3]=(uint8_t)(starts);
    ch[4]=(uint8_t)(numa >> 8);
    ch[5]=(uint8_t)(numa);
    ch[6]=(uint8_t)(numb);
    ch[7]=(uint8_t)(numc >> 8);
    ch[8]=(uint8_t)(numc);
    ch[9]=(uint8_t)(numd >> 8);
    ch[10]=(uint8_t)(numd);

    lens = 11;

    check_crc=count_CRC(ch,lens);

    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
    if(m_serial != NULL){
        m_serial->write(by);
        m_serial->flush();
    }

}

void FridgeDevice::getDevice()
{
    uint8_t address_pos = m_address;
    uint8_t ch[100];
    uint8_t tempa;
    uint32_t lens = 0;
    uint16_t check_crc=0;
    uint16_t cmds=0x0000;
    uint16_t runs=0x0010;
    m_cmds =0x01;
    int nums =1;
    ch[0]= address_pos ;
    ch[1]=m_cmds;
    ch[2]=(uint8_t)(cmds >> 8);
    ch[3]=(uint8_t)(cmds);
    ch[4]=(uint8_t)(runs >> 8);
    ch[5]=(uint8_t)(runs);


    lens = 6;

    check_crc=count_CRC(ch,lens);

    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
    if(m_serial != NULL){
        m_serial->write(by);
        m_serial->flush();
    }
}

void FridgeDevice::readParam()
{
    uint8_t address_pos = m_address;
    uint8_t ch[100];
    uint8_t tempa;
    uint32_t lens = 0;
    uint16_t check_crc=0;
    uint16_t cmds=0x0000;
    uint16_t runs=0x002E;
    m_cmds =0x03;
    int nums =1;
    ch[0]= address_pos ;
    ch[1]=m_cmds;
    ch[2]=(uint8_t)(cmds >> 8);
    ch[3]=(uint8_t)(cmds);
    ch[4]=(uint8_t)(runs >> 8);
    ch[5]=(uint8_t)(runs);


    lens = 6;

    check_crc=count_CRC(ch,lens);

    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
    if(m_serial != NULL){
        m_serial->write(by);
        m_serial->flush();
    }
}

void FridgeDevice::readTemp()
{
    uint8_t address_pos = m_address;
    uint8_t ch[100];
    uint8_t tempa;
    uint32_t lens = 0;
    uint16_t check_crc=0;
    uint16_t cmds=0x0000;
    uint16_t runs=0x0003;
    m_cmds =0x04;
    int nums =1;
    ch[0]= address_pos ;
    ch[1]=m_cmds;
    ch[2]=(uint8_t)(cmds >> 8);
    ch[3]=(uint8_t)(cmds);
    ch[4]=(uint8_t)(runs >> 8);
    ch[5]=(uint8_t)(runs);


    lens = 6;

    check_crc=count_CRC(ch,lens);

    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
    if(m_serial != NULL){
        m_serial->write(by);
        m_serial->flush();
    }
}

void FridgeDevice::readCallPolice()
{
    uint8_t address_pos = m_address;
    uint8_t ch[100];
    uint8_t tempa;
    uint32_t lens = 0;
    uint16_t check_crc=0;
    uint16_t cmds=0x0000;
    uint16_t runs=0x0008;
    m_cmds =0x02;
    int nums =1;
    ch[0]= address_pos ;
    ch[1]=m_cmds;
    ch[2]=(uint8_t)(cmds >> 8);
    ch[3]=(uint8_t)(cmds);
    ch[4]=(uint8_t)(runs >> 8);
    ch[5]=(uint8_t)(runs);


    lens = 6;

    check_crc=count_CRC(ch,lens);

    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
    if(m_serial != NULL){
        m_serial->write(by);
        m_serial->flush();
    }
}

void FridgeDevice::openSetDevice()
{
    if(m_openCmdTimer != NULL){
        m_openCmdTimer->stop();
    }

    if(m_sendDelayCmdTimer != NULL){

        m_sendDelayCmdTimer->stop();
    }

    if(m_openCmdTimer != NULL){
        m_openCmdTimer->start(800);
    }

}

void FridgeDevice::closeSetDevice()
{
    if(m_closeCmdTimer != NULL){
        m_closeCmdTimer->stop();
    }
    if(m_sendDelayCmdTimer != NULL){

        m_sendDelayCmdTimer->stop();
    }

    if(m_closeCmdTimer != NULL){
        m_closeCmdTimer->start(800);
    }

}

void FridgeDevice::setSetTemperature(short mins, short maxs)
{
    if(m_setTempCmdTimer != NULL){
        m_setTempCmdTimer->stop();
    }
    m_setmins = mins;
    m_setmaxs = maxs;
    if(m_sendDelayCmdTimer != NULL){

        m_sendDelayCmdTimer->stop();
    }
    if(m_setTempCmdTimer != NULL){
        m_setTempCmdTimer->start(800);
    }

}

void FridgeDevice::testData()
{
    uint8_t ch[100];
    uint8_t tempa;
    uint16_t check_crc=0;
    int lens = 0;
    ch[0]=0x01;
    ch[1]=0x04;
    ch[2]=0x06;
    ch[3]=0x00;
    ch[4]=0x00;
    ch[5]=0xFE;
    ch[6]=0x0C;
    ch[7]=0xFE;
    ch[8]=0x0C;
    lens = 9;

    // D1 1D
    check_crc=count_CRC(ch,lens);
    tempa =(uint8_t)(check_crc) ;
    ch[lens]=tempa;


    lens++;
    tempa =(uint8_t)(check_crc>>8);
    ch[lens]=tempa;

    lens++;
    QByteArray by((char * )ch,lens);
#ifdef DEBUG_INFOR
    qDebug()<<__func__<<__LINE__<<by.toHex();
#endif
}

short FridgeDevice::getMinsTemp()
{

    return m_minsTemp;
}

short FridgeDevice::getMaxsTemp()
{
    return m_maxsTemp;
}

short FridgeDevice::getCabinetTemp()
{

    return  m_cabinetTemp;
}

short FridgeDevice::getVaporTemp()
{
    return  m_vaporTemp;

}

short FridgeDevice::getCondenTemp()
{
    return  m_condenTemp;

}

int FridgeDevice::getCallPolice(int types)
{
    int rata = m_callPoliceMap.value(types,0);
    return rata;
}

int FridgeDevice::getDeviceStatus()
{
    return m_deviceStatus;
}

void FridgeDevice::sendDelayCmd()
{

    switch (m_sendDelayCmdStatus) {
    case 0:
        getDevice();

        break;
    case 1:
        readParam();

        break;
    case 2:
        readTemp();

        break;
    case 3:
        readCallPolice();

        break;
    default:
        break;

    }
}

bool FridgeDevice::getFridgeRuns()
{
    return m_isFridgeRuns;
}

void FridgeDevice::onDataReceived()
{
    if(m_serial != NULL){

        uint8_t cha[2];
        cha[0]=m_address;
        cha[1]=m_cmds;

        QByteArray data = m_serial->readAll();
        m_currentData.append(data);

        if(m_cmds == 0x05){
            if(m_currentData.size() >= 8){
                QByteArray jusit((char *)cha,2);
                int indexa = m_currentData.indexOf(jusit);
                if(indexa >= 0){
                    unsigned char tempa = m_currentData.at(indexa+2);
                    unsigned char tempb = m_currentData.at(indexa+3);
                    uint16_t cmds1 =tempa;
                    cmds1 = (cmds1 << 8);
                    cmds1+=tempb;

                    tempa = m_currentData.at(indexa+4);
                    tempb = m_currentData.at(indexa+5);
                    uint16_t cmds2 =tempa;
                    cmds2 = (cmds2 << 8);
                    cmds2+=tempb;

                    m_currentData.clear();
                }

            }
            return;
        }

        if(m_cmds == 0x10){
            if(m_currentData.size() >= 8){
                QByteArray jusit((char *)cha,2);
                int indexa = m_currentData.indexOf(jusit);
                if(indexa >= 0){
                    m_currentData.clear();
                }
            }
            return;
        }

        if(m_cmds == 0x03){
            if(m_currentData.size() >= 8){
                QByteArray jusit((char *)cha,2);
                int indexa = m_currentData.indexOf(jusit);

                if(indexa >= 0){
                    int lena = m_currentData.at(indexa+2);
                    if( m_currentData.size() >= (lena+indexa) ){

                        int addsa=6;
                        unsigned char tempa = m_currentData.at(indexa+3 + addsa * 2);
                        unsigned char tempb = m_currentData.at(indexa+4+ addsa * 2);
                        uint16_t cmds1 =tempa;
                        cmds1 = (cmds1 << 8);
                        cmds1+=tempb;
                        m_minsTemp = (short)cmds1;

                        addsa++;
                        tempa = m_currentData.at(indexa+3+ addsa * 2);
                        tempb = m_currentData.at(indexa+4+ addsa * 2);
                        uint16_t cmds2 =tempa;
                        cmds2 = (cmds2 << 8);
                        cmds2+=tempb;
                        m_maxsTemp = (short)cmds2;
                        m_currentData.clear();
                    }

                }
            }
            return;
        }

        if(m_cmds == 0x04){

            if(m_currentData.size() >= 11){
                QByteArray jusit((char *)cha,2);
                int indexa = m_currentData.indexOf(jusit);

                if(indexa >= 0){
                    int lena = m_currentData.at(indexa+2);
                    unsigned char tempa = m_currentData.at(indexa+3 );
                    unsigned char tempb = m_currentData.at(indexa+4);
                    uint16_t cmds1 =tempa;
                    cmds1 = (cmds1 << 8);
                    cmds1+=tempb;
                    m_cabinetTemp = (short)cmds1 / 10;
                    tempa = m_currentData.at(indexa+5 );
                    tempb = m_currentData.at(indexa+6);
                    cmds1 =tempa;
                    cmds1 = (cmds1 << 8);
                    cmds1+=tempb;
                    m_vaporTemp = (short)cmds1 / 10;
                    tempa = m_currentData.at(indexa+7 );
                    tempb = m_currentData.at(indexa+8);
                    cmds1 =tempa;
                    cmds1 = (cmds1 << 8);
                    cmds1+=tempb;
                    m_condenTemp = (short)cmds1 / 10;


                    m_currentData.clear();
                }
            }


            return;
        }
        if(m_cmds == 0x02){

            if(m_currentData.size() >= 6){
                QByteArray jusit((char *)cha,2);
                int indexa = m_currentData.indexOf(jusit);

                if(indexa >= 0){
                    int lena = m_currentData.at(indexa+2);
                    unsigned char tempa = m_currentData.at(indexa+3 );

                    if( (tempa&0x01) == 0 ){
                        m_callPoliceMap.insert(0,0);
                    }else{
                        m_callPoliceMap.insert(0,1);
                    }
                    if( (tempa&0x02) == 0 ){
                        m_callPoliceMap.insert(1,0);
                    }else{
                        m_callPoliceMap.insert(1,1);
                    }
                    if( (tempa&0x04) == 0 ){
                        m_callPoliceMap.insert(2,0);
                    }else{
                        m_callPoliceMap.insert(2,1);
                    }
                    if( (tempa&0x08) == 0 ){
                        m_callPoliceMap.insert(3,0);
                    }else{
                        m_callPoliceMap.insert(3,1);
                    }

                    if( (tempa&0x10) == 0 ){
                        m_callPoliceMap.insert(4,0);
                    }else{
                        m_callPoliceMap.insert(4,1);
                    }


                    if( (tempa&0x20) == 0 ){
                        m_callPoliceMap.insert(5,0);
                    }else{
                        m_callPoliceMap.insert(5,1);
                    }


                    if( (tempa&0x40) == 0 ){
                        m_callPoliceMap.insert(6,0);
                    }else{
                        m_callPoliceMap.insert(6,1);
                    }


                    if( (tempa&0x80) == 0 ){
                        m_callPoliceMap.insert(7,0);
                    }else{
                        m_callPoliceMap.insert(7,1);
                    }

                    m_currentData.clear();
                }
            }


            return;
        }


        if(m_cmds == 0x01){

            if(m_currentData.size() >= 6){
                QByteArray jusit((char *)cha,2);
                int indexa = m_currentData.indexOf(jusit);

                if(indexa >= 0){
                    int lena = m_currentData.at(indexa+2);
                    unsigned char tempa = m_currentData.at(indexa+3 );


                    if( (tempa&0x80) == 0 ){
                        m_deviceStatus = 0;
                    }else{
                        m_deviceStatus = 1;
                    }

                    m_currentData.clear();
                }
            }


            return;
        }


    }
}

void FridgeDevice::onSendDelayCmdTimer()
{
    if(m_sendDelayCmdTimer != NULL){

        m_sendDelayCmdTimer->stop();

        sendDelayCmd();
        m_sendDelayCmdStatus++;
        if(m_sendDelayCmdStatus >= 4){
            m_sendDelayCmdStatus = 0;
        }
        m_sendDelayCmdTimer->start(1000);

    }


}

void FridgeDevice::onOpenDelayCmdTimer()
{
    if(m_openCmdTimer != NULL){
        m_openCmdTimer->stop();
    }
    openDevice();
    if(m_sendDelayCmdTimer != NULL){
        m_sendDelayCmdTimer->start(1000);
    }


}

void FridgeDevice::onCloseDelayCmdTimer()
{
    if(m_closeCmdTimer != NULL){
        m_closeCmdTimer->stop();
    }
    closeDevice();
    if(m_sendDelayCmdTimer != NULL){
        m_sendDelayCmdTimer->start(1000);
    }
}

void FridgeDevice::onSetDelayCmdTimer()
{
    if(m_setTempCmdTimer != NULL){
        m_setTempCmdTimer->stop();
    }

    setSetTemperature( m_setmins  ,m_setmaxs);

    if(m_sendDelayCmdTimer != NULL){
        m_sendDelayCmdTimer->start(1000);
    }
}
